home *** CD-ROM | disk | FTP | other *** search
/ SPACE 1 / SPACE - Library 1 - Volume 1.iso / program / 441 / fplib20 / fpdiv.s < prev    next >
Text File  |  1990-11-23  |  2KB  |  93 lines

  1. * FPDIV.S -- floating point divide    
  2. * Copyright © David Brooks, 1989 All Rights Reserved
  3. *
  4. * This version works by a normal bitwise shift/subtract loop, with separate
  5. * handling of the exponent and a final normalization.  26 bits are computed,
  6. * to allow one normalization and one rounding step.  A certain amount of
  7. * black magic and handwaving are involved, but please note that at no time
  8. * do any bits leave the confines of the computer.
  9. *
  10. * Round-to-even is used for the ambiguous rounding case.
  11. *
  12. * float fpdiv(num, denom); (_fpdiv for explicit call; fpdiv for compiled /)
  13.  
  14.     .globl    fpdiv
  15.     .globl    _fpdiv
  16.  
  17. fpdiv:
  18. _fpdiv:
  19.     move.l    d3,a1            * We don't need no wimpy stack frame
  20.     moveq.l    #0,d0
  21.     move.l    4(sp),d1
  22.     beq    exit            * Numerator 0 - all done
  23.     move.l    8(sp),d2
  24.     beq    div0            * Divide by 0 - overflow
  25.     clr.b    d1            * Work with mantissas
  26.     clr.b    d2
  27.     move.l    #$2000000,d3        * Position of msb of 26-bit field
  28. cmpbit:
  29.     cmp.l    d2,d1            * Compare against new divisor
  30.     blo    nobit
  31.     add.l    d3,d0            * Add in this bit
  32.     sub.l    d2,d1            * and adjust
  33. nobit:
  34.     lsr.l    #1,d2
  35.     lsr.l    #1,d3
  36.     bne    cmpbit            * Done 26 bits?
  37.  
  38.     lsl.l    #6,d0            * Reposition
  39.     tst.l    d1            * If there was a remainder...
  40.     beq    doexp
  41.     addq.l    #2,d0            * record a memory of it.  The 2 bit
  42.                     * .won't be lost by either of the
  43.                     * ..subsequent normalizations
  44. doexp:
  45.     moveq.l    #$7F,d1            * Calculate new exponent
  46.     move.l    d1,d2
  47.     and.b    7(sp),d1
  48.     and.b    11(sp),d2
  49.     sub.w    d2,d1
  50.     add.w    #$41,d1            * Adjust
  51.     tst.l    d0            * Check for already normalized or zero
  52.     bmi    normok
  53. normloop:
  54.     subq.w    #1,d1            * Do one normalize step (there can't
  55.     add.l    d0,d0            * .be more)
  56. normok:
  57.     add.l    #$80,d0            * Round up in most cases
  58.     bcc    round1
  59.     roxr.l    #1,d0            * The rounding caused overflow, sigh
  60.     addq.w    #1,d1
  61. round1:
  62.     tst.b    d0            * See if trailer was exactly 0x80
  63.     bne    ckexp
  64.     and.w    #$FE00,d0        * It was: round to even
  65.  
  66. ckexp:                    * Check exponent for sanity
  67.     tst.w    d1
  68.     ble    underflow
  69.     cmp.w    #$7F,d1
  70.     bgt    overflow
  71. setexp:
  72.     move.b    d1,d0            * Set exponent
  73.  
  74.     move.b    7(sp),d1        * Get signs
  75.     move.b    11(sp),d2
  76.     eor.b    d2,d1            * Form new sign
  77.     and.b    #$80,d1            * Extract it
  78.     or.b    d1,d0
  79. exit:
  80.     move.l    a1,d3
  81.     rts
  82. div0:
  83. overflow:
  84.     moveq.l    #$FFFFFFFF,d0
  85.     moveq.l    #$7F,d1
  86.     bra    setexp
  87.  
  88. underflow:
  89.     moveq.l    #0,d0
  90.     bra    exit
  91.  
  92.     .end
  93.